﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using pttk_htt_hr.Constant;

namespace pttk_htt_hr.Utility
{
    class DataGridUtil
    {
       
        /// <summary>
        /// Method name: DeleteCurrentRowSelected
        /// Desdcribe: 
        ///     1. Xóa dòng đang chọn trên data gridview
        ///     2. Cập nhật lại STT trên grid
        /// </summary>
        /// <param name="dataGridviewName"></param>
        /// <returns></returns>
        public static void DeleteCurrentRowSelected(DataGridView dgv)
        {
            // get current row selected
            if (dgv.CurrentRow != null)
            {
                int CuRowindex = dgv.CurrentRow.Index;

                // kiểm tra 
                if (CuRowindex >= 0)
                {
                    dgv.Rows.RemoveAt(CuRowindex);
                }

                // Re index
                ReIndex(dgv);    
            }
            
        }

        

        /// <summary>
        /// Sắp xếp thứ tự trên  grid
        /// </summary>
        /// <param name="cols"></param>
        /// <param name="dgv"></param>
        /// <returns></returns>

        public static void ReIndex(DataGridView dgv)
        {
            foreach (DataGridViewRow row in dgv.Rows)
            {
                row.Cells[TableColumnMapping.STT].Value = row.Index + 1;
            }
        }

        /// <summary>
        /// Kiểm tra đã tồn tại Mã trong grid chưa
        /// </summary>
        /// <param name="cols"></param>
        /// <param name="dgv"></param>
        /// <returns></returns>

        public static List<int> HasExistedCode(DataGridView dgv, string Code)
        {
            List<int> ExistedCodeIndex = new List<int>();

            // get first code
            string existedCode = dgv.Rows[0].ToString();

            for (int i = 0; i < dgv.RowCount; i++)
            {
                for (int j = i+1; j < dgv.RowCount; j++)
                {
                    string nextCode = dgv.Rows[j].ToString();

                    if (existedCode.Equals(nextCode))
                    {
                        ExistedCodeIndex.Add(i);
                        break;
                    }
                }

                // continue with existed code check
                existedCode = dgv.Rows[i].ToString();
            }

            return ExistedCodeIndex;
        }
        
        /// <summary>
        /// Kiểm tra tồn tại code trong 2 data source
        /// </summary>
        /// <param name="dgv1">Data Source nguồn</param>
        /// <param name="dgv2">Data Source cần thêm vào</param>
        /// <returns></returns>

        public static void RemoveExistedCode(List<ArrayList> dgv1, List<ArrayList> dgv2, int indexCode1, int indexCode2)
        {
            for (int i = 0; i < dgv2.Count; i++)
            {
                ArrayList row2 = dgv2.ElementAt(i);

                string Code2 = row2[indexCode2].ToString();

                for (int j = 0; j < dgv1.Count; j++)
                {
                    ArrayList row1 = dgv1.ElementAt(j);
                    string Code1 = row1[indexCode1].ToString();

                    if (Code2.Equals(Code1))
                    {
                        dgv2.RemoveAt(i);
                    }
                }

            }
        }

        /// <summary>
        /// Rút trích dữ liệu từ gridview
        /// </summary>
        /// <param name="cols"></param>
        /// <param name="dgv"></param>
        /// <returns></returns>
        public static List<Dictionary<string, string>> ExtractData_FromDataGridView(DataGridView dgv, string[] ArrHeaderName)
        {
            List<Dictionary<string, string>> rows = new List<Dictionary<string, string>>();
            Dictionary<string, string> row;

            for (int i = 0; i < dgv.RowCount; i++)
            {
                row = new Dictionary<string, string>();

                for (int j = 0; j < ArrHeaderName.Length; j++)
			    {
                    string key = ArrHeaderName[j];
                    string val = (dgv.Rows[i].Cells[key].Value == null) ? "" : dgv.Rows[i].Cells[key].Value.ToString();
                    row.Add(key, val);
			    }

                rows.Add(row);
            }

            return rows;
        }

        public static List<Dictionary<string, string>> Add_STT(List<Dictionary<string, string>> DataSource)
        {
            List<Dictionary<string,string>> res = new List<Dictionary<string,string>>();

            Dictionary<string, string> Dic;
            for (int i = 0; i < DataSource.Count; i++)
            {
                Dic = DataSource.ElementAt(i);

                if (Dic.ContainsKey(TableColumnMapping.STT))
                {
                    Dic.Remove(TableColumnMapping.STT);
                }

                Dic.Add(TableColumnMapping.STT, Convert.ToString(i + 1));

                res.Add(Dic);

                Dic = new Dictionary<string, string>();
            }

            return res;

        }
        /// <summary>
        /// Thêm data vào data gridview
        /// </summary>
        /// <param name="cols"></param>
        /// <param name="dgv"></param>
        /// <returns></returns>
        public static void AddData_To_DataGridView(List<Dictionary<string,string>> _DataSource, DataGridView dgv, bool hasSTT, string[] ArrHeaderName)
        {
            Dictionary<string, string> Dic;
            List<Dictionary<string, string>> DataSource = new List<Dictionary<string, string>>();

            if (hasSTT)
            {
                DataSource = Add_STT(_DataSource);
            }


            // Add
            List<string> DataRow;
            for (int i = 0; i < DataSource.Count; i++)
            {
                Dic = DataSource.ElementAt(i);
                DataRow = new List<string>();

                for (int j = 0; j < ArrHeaderName.Length; j++)
                {
                    if (Dic.ContainsKey(ArrHeaderName[j]))
                    {
                        DataRow.Add(Dic[ArrHeaderName[j]]);        
                    }
                }

                if (DataRow.Count !=0 )
                {
                    dgv.Rows.Add(DataRow.ToArray());
                }

            }
        }

       /// <summary>
       /// Mục đích: Lấy tất cả các Header Name của data grid view
       /// </summary>
       /// <param name="dgv"></param>
       /// <returns>List<string></returns>
       
        public static List<string> GetAll_ColumnName_DataGridView(DataGridView dgv)
        {
            List<string> LstHeader = new List<string>();

            for (int i = 0; i < dgv.ColumnCount; i++)
            {
                LstHeader.Add(dgv.Columns[i].Name);
            }

            return LstHeader;
        }

        /// <summary>
        /// Mục đích: Lấy data các dòng được chọn trên grid, chỉ lấy những Cột cần lấy
        /// Bước 0: 
        /// Bước 1: Lấy danh sách các row được chọn
        /// Bước 2:
        /// </summary>
        /// <param name="cols"></param>
        /// <param name="dgv"></param>
        /// <returns></returns>
        public static List<ArrayList> ExtractDataFromDataGridViewRowSelected(DataGridView dgv, string[] ArrHeaderName, string CheckBoxName)
        {
            List<ArrayList> results = new List<ArrayList>();
            ArrayList result = new ArrayList();

            /*
             * Bước 1
             */

            List<ArrayList> rows_with_checked_column = Get_RowsSelected(dgv, ArrHeaderName, CheckBoxName);
            

            /*
             * Bước 2
             */

            for (int i = 0; i < rows_with_checked_column.Count; i++)
            {
                ArrayList rows = rows_with_checked_column.ElementAt(i);

                result = new ArrayList();

                foreach (var item in rows)
                {
                    result.Add(item.ToString());
                }
                results.Add(result);
            }
            return results;
        }

        public static List<Dictionary<string,string>> ExtractDataFromDataGridViewRowSelected_LstDic(DataGridView dgv, string[] ArrHeaderName, string CheckBoxName)
        {
            List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
            Dictionary<string, string> result = new Dictionary<string, string>();

            /*
             * Bước 1
             */

            List<Dictionary<string, string>> rows_with_checked_column = Get_RowsSelected_LstDic(dgv, ArrHeaderName, CheckBoxName);


            /*
             * Bước 2
             */

            for (int i = 0; i < rows_with_checked_column.Count; i++)
            {
                Dictionary<string, string> row = rows_with_checked_column.ElementAt(i);

                result = new Dictionary<string, string>();

                string[] keys = row.Keys.ToArray();
                for (int k = 0; k < keys.Length; k++ )
                {
                    for (int j = 0; j < ArrHeaderName.Length; j++)
                    {
                        if (keys[k].Equals(ArrHeaderName[j]))
                        {
                            string key = keys[k];
                            string val = row[key];
                            result.Add(key,val);
                        }
                    }
                    
                }
                results.Add(result);
            }
            return results;
        }

        /// <summary>
        /// Mục đích: Lấy nhiều dòng được chọn trên grid bằng check box
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="ArrHeaderName"></param>
        /// <param name="CheckBoxName"></param>
        /// <returns></returns>
        public static List<ArrayList> Get_RowsSelected(DataGridView dgv, string[] ArrHeaderName, string CheckBoxName) 
        {
            List<ArrayList> rows_with_checked_column = new List<ArrayList>();
            ArrayList cells;

            foreach (DataGridViewRow Row in dgv.Rows)
            {
                // Check row which has selected yet. 
                if (Convert.ToBoolean(((DataGridViewCheckBoxCell)Row.Cells[CheckBoxName]).Value) == true)
                {
                    // Trong cell chứa nhiều cột
                    cells = new ArrayList();

                    // Chọn những cột mà Match với ArrHeaderName đã đưa ra.
                    for (int key = 0; key < ArrHeaderName.Length; key++) // -1, not count on ["checkbox"] key
                    {
                        cells.Add(Row.Cells[ArrHeaderName[key]].Value.ToString());
                    }

                    rows_with_checked_column.Add(cells);
                }
            }

            return rows_with_checked_column;

        }

        public static List<Dictionary<string,string>> Get_RowsSelected_LstDic(DataGridView dgv, string[] ArrHeaderName, string CheckBoxName)
        {
            List<Dictionary<string, string>> rows_with_checked_column = new List<Dictionary<string, string>>();
            Dictionary<string, string> rowI;

            foreach (DataGridViewRow Row in dgv.Rows)
            {
                // Check row which has selected yet. 
                if (Convert.ToBoolean(((DataGridViewCheckBoxCell)Row.Cells[CheckBoxName]).Value) == true)
                {
                    // Trong cell chứa nhiều cột
                    rowI = new Dictionary<string, string>();

                    // Chọn những cột mà Match với ArrHeaderName đã đưa ra.
                    for (int keyI = 0; keyI < ArrHeaderName.Length; keyI++)
                    {
                        string key = ArrHeaderName[keyI];
                        string value = Row.Cells[key].Value.ToString();

                        rowI.Add(key, value);
                    }

                    rows_with_checked_column.Add(rowI);
                }
            }

            return rows_with_checked_column;

        }

        public static bool Check_Match_ColumnName_When_CellClick(DataGridView dgv, string ExpectedColumnName)
        {
            bool res = false;

            if (dgv.CurrentCell != null)
            {
                int SelectedColumnIndex = dgv.CurrentCell.ColumnIndex;
                string SelectedColumnName = dgv.Columns[SelectedColumnIndex].Name;

                if (ExpectedColumnName.Equals(SelectedColumnName))
                {
                    res = true;
                }
            }

            return res;
        }

        public static string Get_CellValue_When_RowClick(DataGridView dgv, string ExpectedColumnName)
        {
            string CellVal = "";


            if (dgv.CurrentRow != null)
            {
                int CuRowindex = dgv.CurrentRow.Index;
               
                CellVal = dgv.Rows[CuRowindex].Cells[ExpectedColumnName].Value.ToString();
            }

            return CellVal;
        }

        /*
            if (dgv.CurrentRow != null)
            {
                int CuRowindex = dgv.CurrentRow.Index;
                dgv.CurrentRow.Cells.
                DataGridViewRow Row = dgv.Rows[CuRowindex];
                int ColumnIndex = Row.Cells[ExpectedColumnName].ColumnIndex;
                ColumnName = dgv.Columns[ColumnIndex].Name;
            }
            return ColumnName;
        */
        public static List<Dictionary<string, string>> grid_data_payback_handle(DataGridView dgvThucDon, List<Dictionary<string, string>> ExtractedData, string[] ArrHeaderName, string[] MainKeys)
        {
            List<Dictionary<string, string>> res = new List<Dictionary<string, string>>();

            // Lấy data hiện thành trên grid
            List<Dictionary<string, string>> Current_Datasource = DataGridUtil.ExtractData_FromDataGridView(dgvThucDon, ArrHeaderName);

            //
            if (Current_Datasource.Count !=0)
            {
                res.AddRange(Current_Datasource);    
            }
            

            if (ExtractedData != null)
            {
                for (int i = 0; i < ExtractedData.Count; i++)
                {
                    Dictionary<string, string> ExDic = ExtractedData.ElementAt(i);
                    if (Current_Datasource.Count == 0)
                    {
                        res.Add(ExDic);
                    }
                    else
                    {
                        bool hasExisted = false;

                        //@ MaTD, TenTD, SoLuong
                        Dictionary<string, string> SourceDic = null;

                        for (int j = 0; j < Current_Datasource.Count; j++)
                        {
                            //@ MaTD, TenTD, SoLuong
                            SourceDic = Current_Datasource.ElementAt(j);

                            // Đảm bảo tất cả các key đều trùng
                            int count = 0;
                            for (int mKey = 0; mKey < MainKeys.Length; mKey++) //MaTD
                            {
                                string k = MainKeys[mKey];
                                string val1 = ExDic[k];
                                string val2 = SourceDic[k];

                                if (val1.Equals(val2))
                                {
                                    count++;
                                }
                            }

                            if (count == MainKeys.Length)
                            {
                                hasExisted = true;
                            }
                        }// End loop j

                        if (!hasExisted)
                        {
                            // Trước khi add vào thêm key vào res;
                            string diffKey = DictionaryUtil.Find_Diff_Key_TowDic(ExDic, SourceDic);

                            ExDic.Add(diffKey, "");

                            res.Add(ExDic);
                        }
                        else
                        {
                            // Trùng thì không add
                        }

                    }// End else
                }

            }

            return res;
        }
    }
}
